import os
import json
import time
import uuid
import hashlib
import sqlite3
import requests
import platform
from datetime import datetime, timedelta

class LicenseManager:
    """授权管理类，处理密钥验证、存储和检查"""
    
    def __init__(self, db_path="robot_zl.db", server_url="https://api.example.com/validate"):
        """
        初始化授权管理器
        
        Args:
            db_path: 数据库路径
            server_url: 验证服务器URL
        """
        self.db_path = db_path
        self.server_url = server_url
        self._create_table()
        
    def _create_table(self):
        """创建授权表"""
        with sqlite3.connect(self.db_path) as conn:
            conn.execute("""
                CREATE TABLE IF NOT EXISTS license_info (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    license_key TEXT NOT NULL,
                    machine_id TEXT NOT NULL,
                    valid_until TEXT NOT NULL,
                    last_check TEXT NOT NULL,
                    is_valid INTEGER DEFAULT 1
                )
            """)
    
    def _get_machine_id(self):
        """获取唯一的机器ID（结合多种硬件信息）"""
        # 获取多种硬件信息
        machine_info = []
        
        # CPU信息
        try:
            machine_info.append(platform.processor())
        except:
            machine_info.append("unknown_cpu")
            
        # 主板序列号（仅Windows）
        try:
            if platform.system() == "Windows":
                import subprocess
                result = subprocess.check_output('wmic csproduct get uuid', shell=True).decode()
                uuid_result = [x.strip() for x in result.split('\n') if x.strip()][1]
                machine_info.append(uuid_result)
        except:
            machine_info.append("unknown_board")
            
        # 添加MAC地址
        try:
            import uuid
            mac = ':'.join(['{:02x}'.format((uuid.getnode() >> elements) & 0xff) 
                           for elements in range(0, 2*6, 8)][::-1])
            machine_info.append(mac)
        except:
            machine_info.append("unknown_mac")
            
        # 添加用户名和计算机名
        try:
            machine_info.append(platform.node())
            machine_info.append(os.getlogin())
        except:
            machine_info.append("unknown_user")
            
        # 组合并哈希
        machine_str = ":".join(machine_info)
        return hashlib.sha256(machine_str.encode()).hexdigest()
    
    def validate_license(self, license_key):
        """
        验证授权密钥
        
        Args:
            license_key: 用户输入的授权密钥
            
        Returns:
            (bool, str): (是否有效, 错误信息)
        """
        # 检查本地缓存
        cached_result = self._check_cached_license(license_key)
        if cached_result:
            return cached_result
            
        # 获取机器ID
        machine_id = self._get_machine_id()
        
        # 向服务器验证
        try:
            response = self._validate_with_server(license_key, machine_id)
            
            if response.get("status") == "success":
                # 保存验证结果
                valid_until = response.get("valid_until")
                self._save_license_info(license_key, machine_id, valid_until)
                return True, "授权验证成功，有效期至: " + valid_until
            else:
                return False, response.get("message", "授权验证失败")
                
        except Exception as e:
            # 如果服务器验证失败，尝试离线验证
            offline_result = self._offline_validate(license_key, machine_id)
            if offline_result[0]:
                return offline_result
            return False, f"授权验证失败: {str(e)}"
    
    def _validate_with_server(self, license_key, machine_id):
        """向服务器发送验证请求"""
        # 实际项目中应该使用HTTPS并加密数据
        try:
            # 模拟服务器响应
            # 实际应用中，这里应该是真实的服务器请求
            # response = requests.post(
            #     self.server_url,
            #     json={
            #         "license_key": license_key,
            #         "machine_id": machine_id
            #     },
            #     timeout=10
            # )
            # return response.json()
            
            # 模拟服务器响应
            # 这里仅用于演示，实际应用中应该连接真实服务器
            valid_until = (datetime.now() + timedelta(days=30)).strftime("%Y-%m-%d %H:%M:%S")
            return {
                "status": "success",
                "message": "授权验证成功",
                "valid_until": valid_until
            }
        except:
            raise Exception("无法连接到授权服务器")
    
    def _offline_validate(self, license_key, machine_id):
        """离线验证授权（备用方案）"""
        # 简单的离线验证逻辑
        # 实际应用中应该使用更复杂的算法
        try:
            # 简单的密钥验证逻辑
            if len(license_key) < 10:
                return False, "无效的授权密钥"
                
            # 检查密钥格式
            parts = license_key.split('-')
            if len(parts) != 5 or any(len(p) != 5 for p in parts):
                return False, "无效的授权密钥格式"
            
            # 简单的有效期计算（仅用于演示）
            seed = sum(ord(c) for c in license_key)
            days_valid = (seed % 100) + 30  # 30-129天
            valid_until = (datetime.now() + timedelta(days=days_valid)).strftime("%Y-%m-%d %H:%M:%S")
            
            # 保存验证结果
            self._save_license_info(license_key, machine_id, valid_until)
            return True, "离线授权验证成功，有效期至: " + valid_until
            
        except Exception as e:
            return False, f"离线验证失败: {str(e)}"
    
    def _save_license_info(self, license_key, machine_id, valid_until):
        """保存授权信息到数据库"""
        now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        
        with sqlite3.connect(self.db_path) as conn:
            # 检查是否已存在此密钥
            cursor = conn.cursor()
            cursor.execute(
                "SELECT id FROM license_info WHERE license_key = ?", 
                (license_key,)
            )
            existing = cursor.fetchone()
            
            if existing:
                # 更新现有记录
                conn.execute(
                    """UPDATE license_info 
                       SET machine_id = ?, valid_until = ?, last_check = ?, is_valid = 1
                       WHERE license_key = ?""",
                    (machine_id, valid_until, now, license_key)
                )
            else:
                # 插入新记录
                conn.execute(
                    """INSERT INTO license_info 
                       (license_key, machine_id, valid_until, last_check, is_valid)
                       VALUES (?, ?, ?, ?, 1)""",
                    (license_key, machine_id, valid_until, now)
                )
    
    def _check_cached_license(self, license_key):
        """检查本地缓存的授权信息"""
        try:
            with sqlite3.connect(self.db_path) as conn:
                cursor = conn.cursor()
                cursor.execute(
                    """SELECT machine_id, valid_until, is_valid 
                       FROM license_info 
                       WHERE license_key = ?""",
                    (license_key,)
                )
                result = cursor.fetchone()
                
                if not result:
                    return None  # 没有缓存记录
                
                machine_id, valid_until, is_valid = result
                
                # 检查机器ID是否匹配
                current_machine_id = self._get_machine_id()
                if machine_id != current_machine_id:
                    return False, "此授权密钥已在其他设备上激活"
                
                # 检查是否有效
                if not is_valid:
                    return False, "此授权密钥已被禁用"
                
                # 检查有效期
                valid_until_date = datetime.strptime(valid_until, "%Y-%m-%d %H:%M:%S")
                if valid_until_date < datetime.now():
                    # 更新状态为无效
                    conn.execute(
                        "UPDATE license_info SET is_valid = 0 WHERE license_key = ?",
                        (license_key,)
                    )
                    return False, "授权已过期，有效期至: " + valid_until
                
                # 更新最后检查时间
                now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                conn.execute(
                    "UPDATE license_info SET last_check = ? WHERE license_key = ?",
                    (now, license_key)
                )
                
                return True, "授权有效，有效期至: " + valid_until
                
        except Exception as e:
            return None  # 出错时返回None，触发重新验证
    
    def check_license_status(self):
        """检查当前授权状态"""
        try:
            with sqlite3.connect(self.db_path) as conn:
                cursor = conn.cursor()
                cursor.execute(
                    """SELECT license_key, valid_until, is_valid 
                       FROM license_info 
                       WHERE machine_id = ? AND is_valid = 1
                       ORDER BY valid_until DESC LIMIT 1""",
                    (self._get_machine_id(),)
                )
                result = cursor.fetchone()
                
                if not result:
                    return False, "未找到有效授权"
                
                license_key, valid_until, is_valid = result
                
                # 检查有效期
                valid_until_date = datetime.strptime(valid_until, "%Y-%m-%d %H:%M:%S")
                if valid_until_date < datetime.now():
                    # 更新状态为无效
                    conn.execute(
                        "UPDATE license_info SET is_valid = 0 WHERE license_key = ?",
                        (license_key,)
                    )
                    return False, "授权已过期，有效期至: " + valid_until
                
                days_left = (valid_until_date - datetime.now()).days
                return True, f"授权有效，还剩 {days_left} 天到期"
                
        except Exception as e:
            return False, f"检查授权状态出错: {str(e)}"